package model

import (
	"fmt"
	"github.com/jinzhu/gorm"
	"kubeInstall/install"
	"kubeInstall/model/app"
	"kubeInstall/utils"
)

// 集群相关操作，安装部署，卸载，升级等等。
//集群配置文件,支持创建，修改，删除，查询。

//安装节点的数据库模型
type HostNameAndIP struct {
	HostName string
	Ip       string
}

//集群配置的数据库模型
type Cluster struct {
	ID          string `json:"id" gorm:"primary_key;column:cluster_id"`
	Status      string `json:"status"`
	ClusterName string `json:"cluster_name"`
	DomainName  string `json:"domain_name"`
	VIP         string `json:"vip" gorm:"column:vip"`
	K8sVersion  string `json:"k8s_version"`
	ApiServer   string `json:"api_server"`
	RepoName    string `json:"repo_name"`
	MaxPodNum   int    `json:"max_pod_num"`
	//network 配置
	PodCIDR string `json:"pod_cidr" gorm:"column:pod_cidr"`
	SvcCIDR string `json:"svc_cidr" gorm:"column:svc_cidr"`
	// ipvs or iptables
	ProxyMode string `json:"proxy_mode"`
	//flannel or calico
	NetworkPlugin string `json:"network_plugin"`
	//存储配置
	StoragePluginType string `json:"storage_plugin_type"`
	//host配置
	ClusterHostNameMap []HostNameAndIP `json:"cluster_host_name_map"`
	MasterNode         []Host          `json:"master_node"`
	WorkerNode         []Host          `json:"worker_node"`
	Master0Handler     *install.AsyncHandler

	BaseModel
}

func (c *Cluster) Create() (Cluster, error) {
	c.ID = utils.GenUUID()
	if err := db.Create(&c).Error; err != nil {
		return Cluster{}, err
	}
	return *c, nil
}

func (c *Cluster) Upgrade(clusterId string) error {
	return nil
}

func (c *Cluster) Get(clusterId string) (Cluster, error) {

	var cluster Cluster
	err := db.Where("cluster_id = ?", clusterId).First(&cluster).Error

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return cluster, fmt.Errorf("host ID %s not found", clusterId)
		}
		return cluster, err
	}

	return cluster, nil

}

func (c *Cluster) Delete(clusterId string) error {
	return nil
}

func (c *Cluster) InitBaseEnv(node Host, clusterHostNameMap []HostNameAndIP, serverIp, serverPath string) error {
	//初始化节点配置
	localPkgPath := "D:\\InstallPkg\\rpmPkgs\\pkgs"
	dockerImagePath := "D:\\InstallPkg\\dockerImages\\master"
	h := install.NewAsyncHandler(node.Username, node.CredentialData, node.IP)

	h.ConfigHostName(node.HostName)
	h.ConfigOsBaseEnv()

	h.InstallNFS(serverIp, serverPath)

	for _, ipAndHostName := range clusterHostNameMap {
		h.ConfigClusterHost(ipAndHostName.Ip, ipAndHostName.HostName)
	}

	h.InstallBasePkgs(localPkgPath)

	if node.Role == "worker" {
		dockerImagePath = "D:\\InstallPkg\\dockerImages\\worker"
	}
	h.LoadDockerImages(dockerImagePath)

	return nil
}

func (c *Cluster) InitMaster0(clusterInfo *Cluster) (*install.KubeAdmJoinOpts, error) {
	//初始化节点配置
	node0 := clusterInfo.MasterNode[0]

	masterIps := make([]string, 0)
	for _, m := range clusterInfo.MasterNode {
		masterIps = append(masterIps, m.IP)
	}
	kubeAdmConfig := &install.KubeAdmConfig{
		MasterIPs:         masterIps,
		VIP:               clusterInfo.VIP,
		Version:           clusterInfo.K8sVersion,
		ApiServer:         clusterInfo.ApiServer,
		PodCIDR:           clusterInfo.PodCIDR,
		SvcCIDR:           clusterInfo.SvcCIDR,
		Repo:              clusterInfo.RepoName,
		ProxyMode:         clusterInfo.ProxyMode,
		MaxPodNum:         clusterInfo.MaxPodNum,
		ClusterName:       clusterInfo.ClusterName,
		NetworkPlugin:     clusterInfo.NetworkPlugin,
		StoragePluginType: clusterInfo.StoragePluginType,
	}
	h := install.NewAsyncHandler(node0.Username, node0.CredentialData, node0.IP)
	c.Master0Handler = h
	joinOpts, err := h.InstallMaster0(kubeAdmConfig)

	return joinOpts, err
}

func (c *Cluster) AddMaster(master Host, joinOpts *install.KubeAdmJoinOpts) error {
	h := install.NewAsyncHandler(master.Username, master.CredentialData, master.IP)
	return h.JoinK8sMaster(joinOpts)
}

func (c *Cluster) AddWorker(worker Host, joinOpts *install.KubeAdmJoinOpts) error {
	h := install.NewAsyncHandler(worker.Username, worker.CredentialData, worker.IP)
	return h.JoinK8sCluster(joinOpts)
}

func (c *Cluster) InstallApp(app app.AppBuilder) error {
	/*	if c.Master0Handler == nil {
			return
		}
	*/
	appyaml := app.ToYaml()
	c.Master0Handler.InstallApps(app.GetAppName(), appyaml)
	return nil
}



/*type Configs struct {
	AppDomain                              string `json:"APP_DOMAIN"`
	CALICOIPV4POOLIPIP                     string `json:"CALICO_IPV4POOL_IPIP"`
	ClusterCidr                            string `json:"CLUSTER_CIDR"`
	ClusterNetwork                         string `json:"CLUSTER_NETWORK"`
	ContainerRuntime                       string `json:"CONTAINER_RUNTIME"`
	DockerAddr                             string `json:"DOCKER_ADDR"`
	ImagePullSecret                        string `json:"IMAGE_PULL_SECRET"`
	MaxPods                                int64  `json:"MAX_PODS"`
	NodeWithMultipleNetworks               string `json:"NODE_WITH_MULTIPLE_NETWORKS"`
	PrometheusRetention                    string `json:"PROMETHEUS_RETENTION"`
	ProxyMode                              string `json:"PROXY_MODE"`
	RegistryAccountName                    string `json:"REGISTRY_ACCOUNT_NAME"`
	RegistryAccountPassword                string `json:"REGISTRY_ACCOUNT_PASSWORD"`
	SandboxImageName                       string `json:"SANDBOX_IMAGE_NAME"`
	SandboxVersion                         string `json:"SANDBOX_VERSION"`
	ServiceCidr                            string `json:"SERVICE_CIDR"`
	StorageDir                             string `json:"STORAGE_DIR"`
	AlertmanagerImage                      string `json:"alertmanager_image"`
	AlertmanagerVersion                    string `json:"alertmanager_version"`
	BaseDir                                string `json:"base_dir"`
	BinDir                                 string `json:"bin_dir"`
	BusyboxImage                           string `json:"busybox_image"`
	BusyboxVersion                         string `json:"busybox_version"`
	CaDir                                  string `json:"ca_dir"`
	CalicoVer                              string `json:"calico_ver"`
	CephCephImage                          string `json:"ceph_ceph_image"`
	CephCephVersion                        string `json:"ceph_ceph_version"`
	CephcsiImage                           string `json:"cephcsi_image"`
	CephcsiVersion                         string `json:"cephcsi_version"`
	ChartmuseumImage                       string `json:"chartmuseum_image"`
	ChartmuseumVersion                     string `json:"chartmuseum_version"`
	ConfigmapReloadImage                   string `json:"configmap_reload_image"`
	ConfigmapReloadVersion                 string `json:"configmap_reload_version"`
	CsiAttacherImage                       string `json:"csi_attacher_image"`
	CsiAttacherVersion                     string `json:"csi_attacher_version"`
	CsiNodeDriverRegistrarImage            string `json:"csi_node_driver_registrar_image"`
	CsiNodeDriverRegistrarVersion          string `json:"csi_node_driver_registrar_version"`
	CsiProvisionerImage                    string `json:"csi_provisioner_image"`
	CsiProvisionerVersion                  string `json:"csi_provisioner_version"`
	CsiSnapshotterImage                    string `json:"csi_snapshotter_image"`
	CsiSnapshotterVersion                  string `json:"csi_snapshotter_version"`
	CurlImage                              string `json:"curl_image"`
	CurlVersion                            string `json:"curl_version"`
	DNSImage                               string `json:"dns_image"`
	DNSInstall                             bool   `json:"dns_install"`
	DNSVersion                             string `json:"dns_version"`
	DockerVersion                          string `json:"docker_version"`
	DownloadPath                           string `json:"download_path"`
	EtcdVersion                            string `json:"etcd_version"`
	FileName                               string `json:"file_name"`
	FlanneldImage                          string `json:"flanneld_image"`
	FlanneldVersion                        string `json:"flanneld_version"`
	GpuInstall                             bool   `json:"gpu_install"`
	GrafanaImage                           string `json:"grafana_image"`
	GrafanaVersion                         string `json:"grafana_version"`
	HelmCertCn                             string `json:"helm_cert_cn"`
	HelmNamespace                          string `json:"helm_namespace"`
	HelmVersion                            string `json:"helm_version"`
	IngressBackend                         string `json:"ingress_backend"`
	KubeBenchImage                         string `json:"kube_bench_image"`
	KubeBenchVersion                       string `json:"kube_bench_version"`
	KubeStateMetricsImage                  string `json:"kube_state_metrics_image"`
	KubeStateMetricsVersion                string `json:"kube_state_metrics_version"`
	KubeVersion                            string `json:"kube_version"`
	KubeappsApprepositoryControllerImage   string `json:"kubeapps_apprepository_controller_image"`
	KubeappsApprepositoryControllerVersion string `json:"kubeapps_apprepository_controller_version"`
	KubeappsChartRepoImage                 string `json:"kubeapps_chart_repo_image"`
	KubeappsChartRepoVersion               string `json:"kubeapps_chart_repo_version"`
	KubeappsChartmuseumHostname            string `json:"kubeapps_chartmuseum_hostname"`
	KubeappsChartsvcImage                  string `json:"kubeapps_chartsvc_image"`
	KubeappsChartsvcVersion                string `json:"kubeapps_chartsvc_version"`
	KubeappsInstall                        bool   `json:"kubeapps_install"`
	KubeappsKubectlImage                   string `json:"kubeapps_kubectl_image"`
	KubeappsKubectlVersion                 string `json:"kubeapps_kubectl_version"`
	KubeappsMinidebImage                   string `json:"kubeapps_minideb_image"`
	KubeappsMinidebVersion                 string `json:"kubeapps_minideb_version"`
	KubeappsMongodbImage                   string `json:"kubeapps_mongodb_image"`
	KubeappsMongodbVersion                 string `json:"kubeapps_mongodb_version"`
	KubeappsNginxImage                     string `json:"kubeapps_nginx_image"`
	KubeappsNginxVersion                   string `json:"kubeapps_nginx_version"`
	KubeappsOauth2ProxyImage               string `json:"kubeapps_oauth2_proxy_image"`
	KubeappsOauth2ProxyVersion             string `json:"kubeapps_oauth2_proxy_version"`
	KubeappsRegistryHostname               string `json:"kubeapps_registry_hostname"`
	KubeappsTillerProxyImage               string `json:"kubeapps_tiller_proxy_image"`
	KubeappsTillerProxyVersion             string `json:"kubeapps_tiller_proxy_version"`
	KubeappsplusDashboardImage             string `json:"kubeappsplus_dashboard_image"`
	KubeappsplusDashboardVersion           string `json:"kubeappsplus_dashboard_version"`
	LocalVolumePath                        string `json:"local_volume_path"`
	LokiImage                              string `json:"loki_image"`
	LokiInstall                            bool   `json:"loki_install"`
	LokiVersion                            string `json:"loki_version"`
	MetricsServerAmd64Image                string `json:"metrics_server_amd64_image"`
	MetricsServerAmd64Version              string `json:"metrics_server_amd64_version"`
	MetricsServerInstall                   bool   `json:"metrics_server_install"`
	NginxIngressImage                      string `json:"nginx_ingress_image"`
	NginxIngressVersion                    string `json:"nginx_ingress_version"`
	NodeExporterImage                      string `json:"node_exporter_image"`
	NodeExporterVersion                    string `json:"node_exporter_version"`
	NodeProblemDetectorImage               string `json:"node_problem_detector_image"`
	NodeProblemDetectorVersion             string `json:"node_problem_detector_version"`
	NpdInstall                             bool   `json:"npd_install"`
	PrometheusImage                        string `json:"prometheus_image"`
	PrometheusVersion                      string `json:"prometheus_version"`
	PromtailImage                          string `json:"promtail_image"`
	PromtailVersion                        string `json:"promtail_version"`
	RegistryPort                           int64  `json:"registry_port"`
	RegistryPrefix                         string `json:"registry_prefix"`
	RepoPort                               int64  `json:"repo_port"`
	RookCephImage                          string `json:"rook_ceph_image"`
	RookCephVersion                        string `json:"rook_ceph_version"`
	StorageLocalVolumeEnabled              bool   `json:"storage_local_volume_enabled"`
	StorageRookCephInstall                 bool   `json:"storage_rook_ceph_install"`
	TillerCertCn                           string `json:"tiller_cert_cn"`
	TillerImage                            string `json:"tiller_image"`
	TillerSa                               string `json:"tiller_sa"`
	TillerVersion                          string `json:"tiller_version"`
	TraefikImage                           string `json:"traefik_image"`
	TraefikVersion                         string `json:"traefik_version"`
}
*/
